using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace NodeCanvas.DialogueTrees
{
	[AddComponentMenu("")]
	[Name("✫ Multiple Choice")]
	[Description("Prompt a Dialogue Multiple Choice. A choice will be available if the connection's condition is true or there is no condition on that connection. The Actor selected is used for the Condition checks as well as will Say the selection if the option is checked.")]
	public class DLGMultipleChoiceNode : DLGNodeBase
	{
		[Serializable]
		public class Choice
		{
			public bool isUnfolded = true;

			public Statement statement;

			public Choice(Statement statement)
			{
				this.statement = statement;
			}
		}

		public float availableTime;

		public bool saySelection;

		[SerializeField]
		[HideInInspector]
		private List<Choice> possibleOptions = new List<Choice>();

		private bool isWaitingChoice;

		public override string nodeName
		{
			get
			{
				return base.nodeName + " " + base.finalActorName;
			}
		}

		public override int maxOutConnections
		{
			get
			{
				return -1;
			}
		}

		public override Type outConnectionType
		{
			get
			{
				return typeof(ConditionalConnection);
			}
		}

		protected override Status OnExecute()
		{
			if (base.outConnections.Count == 0)
			{
				base.DLGTree.StopGraph();
				return Error("There are no connections to the Multiple Choice Node!");
			}
			if (!base.finalActor)
			{
				base.DLGTree.StopGraph();
				return Error("Actor not found");
			}
			base.DLGTree.currentNode = this;
			Dictionary<Statement, int> dictionary = new Dictionary<Statement, int>();
			for (int i = 0; i < base.outConnections.Count; i++)
			{
				if ((base.outConnections[i] as ConditionalConnection).CheckCondition(base.finalActor, base.finalBlackboard))
				{
					Statement key = possibleOptions[i].statement.BlackboardReplace(base.finalBlackboard);
					dictionary[key] = i;
				}
			}
			if (dictionary.Count == 0)
			{
				Debug.Log("Multiple Choice Node has no available options. Dialogue Ends");
				base.DLGTree.StopGraph();
				return Status.Failure;
			}
			if (availableTime > 0f)
			{
				StartCoroutine(CountDown());
			}
			EventHandler.Dispatch(DLGEvents.OnDialogueOptions, new DialogueOptionsInfo(dictionary, availableTime, OnOptionSelected));
			return Status.Running;
		}

		private IEnumerator CountDown()
		{
			isWaitingChoice = true;
			float timer = 0f;
			while (timer < availableTime)
			{
				if (!base.DLGTree.isRunning || !isWaitingChoice)
				{
					yield break;
				}
				timer += Time.deltaTime;
				yield return null;
			}
			for (int num = base.outConnections.Count - 1; num >= 0; num--)
			{
				ConditionalConnection conditionalConnection = base.outConnections[num] as ConditionalConnection;
				if (conditionalConnection.CheckCondition(base.finalActor, base.finalBlackboard))
				{
					OnOptionSelected(num);
					break;
				}
			}
		}

		private void OnOptionSelected(int index)
		{
			base.status = Status.Success;
			if (base.DLGTree.isRunning)
			{
				isWaitingChoice = false;
				Action action = delegate
				{
					base.outConnections[index].Execute(base.finalActor, base.finalBlackboard);
				};
				if (saySelection && base.finalActor != null)
				{
					Statement statement = possibleOptions[index].statement.BlackboardReplace(base.finalBlackboard);
					base.finalActor.Say(statement, action);
				}
				else
				{
					action();
				}
			}
		}

		public override void OnPortConnected(int index)
		{
			if (possibleOptions.Count < base.outConnections.Count)
			{
				possibleOptions.Insert(index, new Choice(new Statement("...")));
			}
		}

		public override void OnPortDisconnected(int index)
		{
		}
	}
}
